﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FineSoft.Controls
{
	public static class WebBrowserExtendMethod
	{
		private static object Eval(this System.Windows.Controls.WebBrowser browser, string script)
		{
			return browser.InvokeScript("eval", script);
		}

		public static bool IsComponentAtPosition(this System.Windows.Controls.WebBrowser browser, string componentId, System.Windows.Point position)
		{
			System.Windows.Point componentPosition = GetPositionOfComponent(browser, componentId);
			if (componentPosition.X > position.X || componentPosition.X + GetComponentWidth(browser, componentId) < position.X)
				return false;
			if (componentPosition.Y > position.Y || componentPosition.Y + GetComponentHeight(browser, componentId) < position.Y)
				return false;
			return true;
		}

		public static System.Windows.Point GetPositionOfComponent(this System.Windows.Controls.WebBrowser browser, string componentId)
		{
			object result = Eval(browser, string.Format(@"(function()
{{
	var element=Ext.getCmp('{0}').el;
	if(element)
	{{
		var position=element.getXY();
		return {{x:position[0],y:position[1]}};
	}}
	return {{x:0,y:0}};
}})()", componentId));
			return new System.Windows.Point((int)InvokeMember(result, "x"), (int)InvokeMember(result, "y"));
		}

		public static int GetComponentWidth(this System.Windows.Controls.WebBrowser browser, string componentId)
		{
			return (int)Eval(browser, string.Format("var component=Ext.getCmp('{0}');component.el?component.getWidth():0", componentId));
		}

		public static int GetComponentHeight(this System.Windows.Controls.WebBrowser browser, string componentId)
		{
			return (int)Eval(browser, string.Format("var component=Ext.getCmp('{0}');component.el?component.getHeight():0", componentId));
		}

		public static string[] GetComponentIdsAtPosition(this System.Windows.Controls.WebBrowser browser, string[] allComponentIds, System.Windows.Point position)
		{
			return allComponentIds.Where(id => IsComponentAtPosition(browser, id, position)).ToArray();
		}

		public static System.Windows.Rect GetRectangleOfComponent(this System.Windows.Controls.WebBrowser browser, string componentId)
		{
			System.Windows.Point position = GetPositionOfComponent(browser, componentId);
			return new System.Windows.Rect(position.X, position.Y, GetComponentWidth(browser, componentId), GetComponentHeight(browser, componentId));
		}

		public static bool IsComponentOverlapWidthRectangle(this System.Windows.Controls.WebBrowser browser, string componentId, System.Windows.Rect rectangle)
		{
			System.Windows.Rect componentRectangle = GetRectangleOfComponent(browser, componentId);
			if (componentRectangle.Left > rectangle.Left + rectangle.Width)
				return false;
			if (componentRectangle.Top > rectangle.Top + rectangle.Height)
				return false;
			if (componentRectangle.Left + componentRectangle.Width < rectangle.Left)
				return false;
			if (componentRectangle.Top + componentRectangle.Height < rectangle.Top)
				return false;

			return true;
		}

		public static string[] GetComponentIdsOverlapWidthRectangle(this System.Windows.Controls.WebBrowser browser, string[] allComponentIds, System.Windows.Rect rectangle)
		{
			return allComponentIds.Where(id => IsComponentOverlapWidthRectangle(browser, id, rectangle)).ToArray();
		}

		private static object InvokeMember(object o, string name)
		{
			return o.GetType().InvokeMember(name, System.Reflection.BindingFlags.GetProperty, null, o, null);
		}

		private static void RefreshViewPort(this System.Windows.Controls.WebBrowser browser, string viewPortId, string viewPortConfig)
		{
			string sciprt = string.Format("var viewPort=Ext.getCmp('{0}');viewPort.destroy();{1}", viewPortId, viewPortConfig);
			browser.Eval(string.Format("var viewPort=Ext.getCmp('{0}');viewPort.destroy();{1}", viewPortId, viewPortConfig));
		}

		public static void RefreshComponentInItems(this System.Windows.Controls.WebBrowser browser, string containerId, string componentId, string componentConfig)
		{
			if (containerId == null)
			{
				RefreshViewPort(browser,componentId,componentConfig);
				return;
			}

			browser.Eval(string.Format(@"var container=Ext.getCmp('{0}');
var component=Ext.getCmp('{1}');
var newComponent={2};
if(component)
{{
	var index=container.items.indexOf(component);
	container.remove(component);
	container.insert(index,newComponent);
}}
else container.add(newComponent)", containerId, componentId, componentConfig));
		}
	}
}